package com.chrray.position.service.auth.impl;


import com.alibaba.fastjson.JSONObject;
import com.chrray.position.constants.RedisConstants;
import com.chrray.position.entity.position.SysRole;
import com.chrray.position.entity.position.SysUser;
import com.chrray.position.enums.YesNoEnum;

import com.chrray.position.mapper.position.SysRoleMapper;
import com.chrray.position.mapper.position.SysUserMapper;
import com.chrray.position.pojo.dto.auth.AllUserAddRequest;
import com.chrray.position.pojo.dto.auth.WebAllUserUpdateRequest;
import com.chrray.position.pojo.dto.auth.LoginDto;
import com.chrray.position.pojo.dto.auth.AllUserUpRequest;
import com.chrray.position.pojo.dto.auth.UpdatePasswordDto;
import com.chrray.position.pojo.dto.auth.UserListDto;
import com.chrray.position.pojo.vo.auth.LoginVo;
import com.chrray.position.service.auth.MaSysUserService;
import com.chrray.position.util.md5.Md5Utils;
import com.chrray.position.util.redis.RedisUtils;
import com.chrray.position.util.result.PageBean;
import com.chrray.position.util.result.ResponseResult;
import com.chrray.position.util.result.ResultEnum;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import java.time.LocalDateTime;

import static com.chrray.position.constants.RedisConstants.UPDATE_PASSWORD_TIME;
import static com.chrray.position.util.result.ResponseResults.fail;
import static com.chrray.position.util.result.ResponseResults.success;


/**
 * 系统用户表
 */
@Service
public class MaSysUserServiceImpl implements MaSysUserService {
    @Resource
    private SysUserMapper sysUserMapper;

    @Resource
    private SysRoleMapper sysRoleMapper;

    @Autowired
    private RedisUtils redisUtils;

    @Autowired
    private Environment environment;


    @Override
    public ResponseResult updatePassword(UpdatePasswordDto dto) {


        if (ObjectUtils.isEmpty(dto) || StringUtils.isBlank(dto.getPassword()) || StringUtils.isBlank(dto.getOldPassword())) {
            return fail(ResultEnum.BAD_PASSWORD_REQUEST);
        }
        if(dto.getPassword().length()<8){
            return fail(ResultEnum.BAD_PASSWORD_REQUEST);
        }

        SysUser wtSysUser = sysUserMapper.selectByPrimaryKey(dto.getLoginSysUserId());
        String oldPassword = Md5Utils.MD5(dto.getOldPassword());
        if (!oldPassword.equals(wtSysUser.getPassword())) {
            return fail(ResultEnum.USER_OLD_PASSWORD_ERROR);

        }
        wtSysUser.setPassword(Md5Utils.MD5(dto.getPassword()));
        sysUserMapper.updateByPrimaryKeySelective(wtSysUser);
        String key=UPDATE_PASSWORD_TIME+dto.getLoginSysUserId();
        redisUtils.setHour(key,"1",24*30);
        return success();
    }

    @Override
    public ResponseResult<LoginVo> login(LoginDto login) {
        if (StringUtils.isNotBlank(login.getAccount()) && StringUtils.isNotBlank(login.getPassword())) {

            String loginPwd = Md5Utils.MD5(login.getPassword());

            SysUser user = sysUserMapper.selectByUserNameAndPassword(login.getAccount(), loginPwd);

            String passwordErrorKey=  RedisConstants.LOGIN_PASSWORD_ERROR_TIME+login.getAccount();
            Integer passwordErrorTime = redisUtils.getInteger(passwordErrorKey);
            if(ObjectUtils.isEmpty(passwordErrorTime)){
                passwordErrorTime=0;
            }
            if(passwordErrorTime>=3){
                return fail(ResultEnum.LOGIN_PASSWORD_ERROR_TIME);
            }

            if (!ObjectUtils.isEmpty(user)) {

                if (user.getState().equals(YesNoEnum.NO.getCode())) {
                    return fail(ResultEnum.LOGIN_USER_WARN);
                }

                SysRole sysRole = sysRoleMapper.selectByPrimaryKey(user.getRoleId());
                if (ObjectUtils.isEmpty(sysRole)) {
                    return fail(ResultEnum.LOGIN_USER_ROLE_WARN);
                }
                if (!sysRole.getState().equals(1)) {
                    return fail(ResultEnum.LOGIN_USER_ROLE_WARN);

                }

                String token = Md5Utils.MD5(LocalDateTime.now().toString() + user.getId());
                redisUtils.setHour("webUser_" + token, JSONObject.toJSONString(user) +"",24*7 );



                LoginVo loginVo = new LoginVo();
                loginVo.setUserName(user.getUserName());
                loginVo.setAccount(user.getAccount());
                loginVo.setToken("webUser_" + token);

                String key=UPDATE_PASSWORD_TIME+user.getId();
                Object o = redisUtils.get(key);
                if(ObjectUtils.isEmpty(o)){
                    loginVo.setNeedUpdatePassword(YesNoEnum.YES.getCode());
                }else {
                    loginVo.setNeedUpdatePassword(YesNoEnum.NO.getCode());
                }
                redisUtils.del(passwordErrorKey);
                return success(loginVo);
            } else {
                passwordErrorTime+=1;
                redisUtils.set(passwordErrorKey,passwordErrorTime,60*10);

                return fail(ResultEnum.LOGIN_USER_ERROR);
            }
        } else {
            return fail(ResultEnum.LOGIN_USER_NULL);

        }
    }

    @Override
    public ResponseResult resettingPwd(Long id) {
        SysUser sysUser = new SysUser();
        sysUser.setId(id);
        String defaultPassword = environment.getProperty("user.defaultPassword");
        sysUser.setPassword(Md5Utils.MD5(Md5Utils.MD5(defaultPassword)));
        sysUserMapper.updateByPrimaryKeySelective(sysUser);
        return success();
    }

    @Override
    public ResponseResult updateUser(AllUserAddRequest dto) {

        if (StringUtils.isNotBlank(dto.getAccount())) {
            SysUser oldUser = sysUserMapper.selectByUserName(dto.getAccount());

            if (!ObjectUtils.isEmpty(oldUser) && !oldUser.getId().equals(dto.getId())) {
                return fail(ResultEnum.USER_EXIST_USER_NAME);
            }
        }
        SysUser sysUser = new SysUser();
        BeanUtils.copyProperties(dto, sysUser);
        if (!ObjectUtils.isEmpty(dto) && StringUtils.isNotBlank(dto.getPassword())) {
            dto.setPassword(Md5Utils.MD5(sysUser.getPassword()));
        }
        sysUserMapper.updateByPrimaryKeySelective(sysUser);
        return success();
    }

    @Override
    @Transactional
    public ResponseResult addUser(AllUserAddRequest dto) {

        if (ObjectUtils.isEmpty(dto.getAccount()) || ObjectUtils.isEmpty(dto.getPassword()) || ObjectUtils.isEmpty(dto.getRoleId())) {
            return fail(ResultEnum.MUST_PARAMETER);
        }

        if (StringUtils.isNotBlank(dto.getAccount())) {
            SysUser oldUser = sysUserMapper.selectByUserName(dto.getAccount());

            if (!ObjectUtils.isEmpty(oldUser)) {
                return fail(ResultEnum.USER_EXIST_USER_NAME);
            }
        }
        SysUser sysUser = new SysUser();
        BeanUtils.copyProperties(dto, sysUser);
        sysUser.setPassword(Md5Utils.MD5(sysUser.getPassword()));
        sysUser.setState(1);
        sysUserMapper.insertSelective(sysUser);
        return success();
    }

    @Override
    public ResponseResult upOrDownUser(AllUserUpRequest sysUser) {

        SysUser sysUser1 = new SysUser();
        sysUser1.setId(sysUser.getId());
        sysUser1.setState(sysUser.getState());
        sysUserMapper.updateByPrimaryKeySelective(sysUser1);
        return success();
    }


    @Override
    public SysUser selectById(Long id) {

        SysUser sysUser = sysUserMapper.selectByPrimaryKey(id);
        SysRole sysRole = sysRoleMapper.selectByPrimaryKey(sysUser.getRoleId());
        sysUser.setRoleName(ObjectUtils.isEmpty(sysRole)?"":sysRole.getRoleName());
        return sysUser;
    }

    @Override
    public ResponseResult<SysUser> getSysUser(Long id) {
        SysUser sysUser = sysUserMapper.selectByPrimaryKey(id);
        sysUser.setPassword(null);
        SysRole role = sysRoleMapper.selectByPrimaryKey(sysUser.getRoleId());
        sysUser.setRoleName(ObjectUtils.isEmpty(role) ? "" : role.getRoleName());
        return success(sysUser);
    }

    @Override
    public ResponseResult updateSysUser(WebAllUserUpdateRequest dto) {
        if (ObjectUtils.isEmpty(dto) || StringUtils.isBlank(dto.getPassword()) || StringUtils.isBlank(dto.getOldPassword())) {
            return fail(ResultEnum.BAD_PASSWORD_REQUEST);
        }
        SysUser wtSysUser = sysUserMapper.selectByPrimaryKey(dto.getLoginSysUserId());
        String oldPassword = Md5Utils.MD5(dto.getOldPassword());
        if (!oldPassword.equals(wtSysUser.getPassword())) {
            return fail(ResultEnum.USER_OLD_PASSWORD_ERROR);
        }
        SysUser sysUser = new SysUser();
        BeanUtils.copyProperties(dto, sysUser);
        sysUser.setPassword( Md5Utils.MD5(dto.getPassword()));
        sysUser.setId(dto.getLoginSysUserId());
        sysUserMapper.updateByPrimaryKeySelective(sysUser);
        return success();
    }

    @Override
    public ResponseResult<PageBean<SysUser>> listUser(UserListDto dto) {
        PageHelper.startPage(dto.getPage(), dto.getRows());
        Page<SysUser> list = (Page<SysUser>) sysUserMapper.listUser(dto.getRoleId(), dto.getUserName());
        list.getResult().stream().forEach(
                sysUser -> {
                    SysRole sysRole = sysRoleMapper.selectByPrimaryKey(sysUser.getRoleId());
                    sysUser.setRoleName(ObjectUtils.isEmpty(sysRole)?"":sysRole.getRoleName());
                }
        );
        return success(list);
    }

    @Override
    @Transactional
    public ResponseResult deleteUser(Long id) {
        SysUser sysUser1 = new SysUser();
        sysUser1.setId(id);
        sysUser1.setDeleted(YesNoEnum.YES.getCode());
        sysUserMapper.updateByPrimaryKeySelective(sysUser1);
        return success();
    }
}